package com.wl.lib.utils

import android.annotation.SuppressLint
import android.content.Context
import android.os.StatFs
import android.util.Log
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.security.MessageDigest
import java.util.zip.ZipEntry
import java.util.zip.ZipInputStream


/**
 *
 * Created by wangliang on 2024/11/26
 */
object FileUtils {

    fun getInternalFileAvailableSpace(context: Context): Long {
        val statFs = StatFs(context.filesDir.absolutePath)
        val total = statFs.totalBytes
        Log.d("WLTest", "total ${formatSize(total)}")
        val available = statFs.availableBytes
        return available
    }

    fun getExternalFileAvailableSpace(context: Context): Long {
        val statFs = StatFs(context.getExternalFilesDir(null)?.absolutePath)
        val total = statFs.totalBytes
        Log.d("WLTest", "total ${formatSize(total)}")
        val available = statFs.availableBytes
        return available
    }

    fun getExternalFileWebRootPath(context: Context): String {
        val webRootPath = context.getExternalFilesDir(null)?.absolutePath + "/web/"
        if (!File(webRootPath).exists()) {
            File(webRootPath).mkdirs()
        }
        return webRootPath
    }

    fun getFilenameFromUrl(url: String): String {
        val parts = url.split("/")
        return parts.last()
    }

    fun getFileSuffix(filename: String): String {
        if (!filename.contains("."))
            return ""
        val parts = filename.split(".")
        return parts.last()
    }

    fun getFilenameWithoutSuffix(filename: String): String {
        if (!filename.contains("."))
            return filename
        val parts = filename.split(".")
        return parts.first()
    }

    fun isFileExists(filePath: String): Boolean {
        return File(filePath).exists()
    }

    fun deleteFile(filePath: String): Boolean {
        val file = File(filePath)
        if (file.isDirectory) {
            val files = file.listFiles()
            files?.forEach {
                deleteFile(it.absolutePath)
            }
        } else {
            file.delete()
        }
        return true
    }

    @SuppressLint("DefaultLocale")
    fun formatSize(bytes: Long): String {
        val kilobyte = 1024L
        val megabyte = kilobyte * 1024
        val gigabyte = megabyte * 1024

        return when {
            bytes >= gigabyte -> String.format("%.2f GB", bytes.toDouble() / gigabyte)
            bytes >= megabyte -> String.format("%.2f MB", bytes.toDouble() / megabyte)
            bytes >= kilobyte -> String.format("%.2f KB", bytes.toDouble() / kilobyte)
            else -> "$bytes Bytes"
        }
    }

    fun generateMd5FromUrl(url: String): String {
        val md5Digest = MessageDigest.getInstance("MD5")
        val hashBytes = md5Digest.digest(url.toByteArray(Charsets.UTF_8))
        return hashBytes.joinToString("") { "%02x".format(it) } // 将字节转换为十六进制
    }

    // 解压 ZIP 文件
    fun unzip(zipFilePath: String, outputDir: String) {
        val buffer = ByteArray(1024)

        // 确保输出目录存在
        val outputDirectory = File(outputDir)
        if (!outputDirectory.exists()) {
            outputDirectory.mkdirs()
        }

        ZipInputStream(FileInputStream(zipFilePath)).use { zipInputStream ->
            var zipEntry: ZipEntry?
            while (zipInputStream.nextEntry.also { zipEntry = it } != null) {
                val file = File(outputDir, zipEntry!!.name)

                // 如果是目录，则创建目录
                if (zipEntry!!.isDirectory) {
                    file.mkdirs()
                } else {
                    // 确保父目录存在
                    file.parentFile?.mkdirs()

                    // 写入文件内容
                    FileOutputStream(file).use { fileOutputStream ->
                        var length: Int
                        while (zipInputStream.read(buffer).also { length = it } > 0) {
                            fileOutputStream.write(buffer, 0, length)
                        }
                    }
                }
            }
        }
    }
}